package com.zhiche.wms.service.mqtt;

import com.zhiche.wms.service.utils.MQTTUtil;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author: caiHua
 * @Description: 发布消息的回调类
 * 必须实现MqttCallback的接口并实现对应的相关接口方法CallBack 类将实现 MqttCallBack。
 * 每个客户机标识都需要一个回调实例。在此示例中，构造函数传递客户机标识以另存为实例数据。
 * 在回调中，将它用来标识已经启动了该回调的哪个实例。
 * 必须在回调类中实现三个方法：
 * public void messageArrived(MqttTopic topic, MqttMessage message)接收已经预订的发布。
 * public void connectionLost(Throwable cause)在断开连接时调用。
 * public void deliveryComplete(MqttDeliveryToken token))
 * 接收到已经发布的 QoS 1 或 QoS 2 消息的传递令牌时调用。
 * 由 MqttClient.connect 激活此回调。
 * @Date: Create in 14:07 2019/8/28
 */
public class PushCallback implements MqttCallback {
    private static final Logger LOGGER = LoggerFactory.getLogger(PushCallback.class);

    private static MqttClientPersistence persistence = new MemoryPersistence();

    @Override
    public void connectionLost (Throwable throwable) {
        LOGGER.info("连接断开，可以做重连");
        try {
            // 连接丢失后，一般在这里面进行重连
            MqttClient client = new MqttClient(MQTTUtil.serviceURI,MQTTUtil.clientID, persistence);
            MqttConnectOptions connectOptions = new MqttConnectOptions();
            connectOptions.setUserName(MQTTUtil.username);
            connectOptions.setPassword(MQTTUtil.password.toCharArray());
            //设置是否清空session,false表示服务器会保留客户端的连接记录，true表示每次连接到服务器都以新的身份连接
            connectOptions.setCleanSession(false);
            //设置超时时间 单位为秒
            connectOptions.setConnectionTimeout(60);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
            connectOptions.setKeepAliveInterval(20);
            client.connect(connectOptions);
        } catch (Exception e) {
            LOGGER.error("重连失败" + e.getMessage());
        }
    }

    @Override
    public void messageArrived (String topic, MqttMessage mqttMessage) throws Exception {
        // subscribe后得到的消息会执行到这里面
        LOGGER.info("接收消息主题 : " + topic);
        LOGGER.info("接收消息Qos : " + mqttMessage.getQos());
        LOGGER.info("接收消息内容 : " + new String(mqttMessage.getPayload()));
    }

    @Override
    public void deliveryComplete (IMqttDeliveryToken iMqttDeliveryToken) {
        LOGGER.info("deliveryComplete---------" + iMqttDeliveryToken.isComplete());
    }
}
